	/*
	Control Unit for BURP ECE152b Spring 2010
	OPCODE    |    Operation
	--------------------------
	4'b0000  --- NoOp
	4'b0001  --- JC
	4'b0010  --- JMP
	4'b0011  --- MOV
	4'b0100  --- MVI
	4'b0101  --- INC
	4'b0110  --- ADD
	4'b0111  --- SUB
	4'b1000  --- AND
	4'b1001  --- OR
	4'b1010  --- SC
	4'b1011  --- CC
	4'b1100  --- PUSH
	4'b1101  --- POP
	4'b1110  --- IN
	4'b1111  --- OUT

	**********************
	*/

	module Controller(CLK, RST, CARRY_FROM_ALU, ALUcarry, IR, IR_IN, IR_OUT, PC_LOW_IN, PC_LOW_OUT, PC_LOW_INC, PC_LOW_RST, PC_HIGH_IN, PC_HIGH_INC, PC_HIGH_RST, ACCUM_IN, SMR_IN, SMR_OUT, REG_SELECT, R_IN, R_OUT, INC, M, S, LED_REG_IN, DIP_OUT, STACK_OVERFLOW, STACK_UNDERFLOW, INVCLOCK);
	  input[7:0] IR; 
	  input CLK, RST, CARRY_FROM_ALU;
	  output ALUcarry, IR_IN, IR_OUT, PC_LOW_IN, PC_LOW_OUT, PC_LOW_INC, PC_LOW_RST, PC_HIGH_IN, PC_HIGH_INC, PC_HIGH_RST, ACCUM_IN, SMR_IN, SMR_OUT, R_IN, R_OUT, INC, M, LED_REG_IN, DIP_OUT; 
	  reg ALUcarry, IR_IN, IR_OUT, PC_LOW_IN, PC_LOW_OUT, PC_LOW_INC, PC_LOW_RST, PC_HIGH_IN, PC_HIGH_INC, PC_HIGH_RST, ACCUM_IN, SMR_IN, SMR_OUT, R_IN, R_OUT, INC, M, LED_REG_IN, DIP_OUT;
	  output[3:0] REG_SELECT;
	  reg[3:0] REG_SELECT;
	  output[3:0] S;
	  reg[3:0] S;
	  reg[3:0] STACK_PTR;
	  reg[4:0] i; // i needs to count to 8!
	  output STACK_OVERFLOW, STACK_UNDERFLOW;
	  reg    STACK_OVERFLOW, STACK_UNDERFLOW;
	  reg carry_storage; // place to store the carry bit
	  reg temp_carry;
	  reg firstStep;
	  
	  output INVCLOCK;
	  
	  assign INVCLOCK = ~CLK;
	  
	  initial
	  begin
		ALUcarry = 0;
		IR_IN = 0;
		IR_OUT = 0;
		PC_LOW_IN = 0;
		PC_LOW_OUT = 0;
		PC_LOW_INC = 0;
		PC_LOW_RST = 0;
		PC_HIGH_IN = 0;
		PC_HIGH_INC = 0;
		PC_HIGH_RST = 0;
		ACCUM_IN = 0;
		SMR_IN = 0;
		SMR_OUT = 0;
		R_IN = 0;
		R_OUT = 0;
		INC = 0;
		M = 0;
		LED_REG_IN = 0;
		DIP_OUT = 0;
	    STACK_PTR = 0;
		PC_HIGH_RST = 1;
		PC_LOW_RST = 1;
		i = 0;
		firstStep = 1;
		carry_storage = 0;
	  end
	  
	  always@(posedge CLK or posedge RST) begin
	      if(RST)
	      begin
			ALUcarry = 0;
			IR_IN = 0;
			IR_OUT = 0;
			PC_LOW_IN = 0;
			PC_LOW_OUT = 0;
			PC_LOW_INC = 0;
			PC_LOW_RST = 0;
			PC_HIGH_IN = 0;
			PC_HIGH_INC = 0;
			PC_HIGH_RST = 0;
			ACCUM_IN = 0;
			SMR_IN = 0;
			SMR_OUT = 0;
			R_IN = 0;
			R_OUT = 0;
			INC = 0;
			M = 0;
			LED_REG_IN = 0;
			DIP_OUT = 0;
			STACK_PTR = 0;
			PC_HIGH_RST = 1;
			PC_LOW_RST = 1;
			i = 0;
			firstStep = 1;
			carry_storage = 0;
	      end 
		  else begin
	      //*********************
	      //set all command signals low
	      //*********************
	      
	      //ALUcarry = 0;
		  IR_IN = 0;
		  //IR_OUT = 0;
		  //IR_OUT must be manually disabled.
		  PC_LOW_IN = 0;
		  //PC_LOW_OUT = 0;
		  // PC LOW OUT has to be manually disabled.
		  PC_LOW_INC = 0;
		  PC_LOW_RST = 0;
		  PC_HIGH_IN = 0;
		  PC_HIGH_INC = 0;
		  PC_HIGH_RST = 0;
		  //ACCUM_IN = 0;
		  // ACCUM_IN has to be manually disabled
		  //SMR_IN = 0;
		  // SMR_IN has to be manually disabled
		  // SMR_OUT = 0;
		  // SMR_OUT has to be manually disabled
		  R_IN = 0;
		  //R_OUT = 0;
	      // R_OUT must be manually disabled.
		  //INC = 0;
		  // INC must be manually disabled
		  //M = 0;
		  // M doens't really need to be reset since it's set every time.
		  LED_REG_IN = 0;
		  //DIP_OUT = 0;
		  //DIP_OUT must be manually disabled.

		  
	      case(IR[7:4])
	        4'b0000:begin //NO OP
				case(i)
					0:  IR_IN = 1;
					//-------------------------------
					//begin increment program counter
					//-------------------------------
					1: 	begin
						IR_OUT = 0;
						PC_LOW_OUT = 1;
						INC = 1;
						//ALU_FUNC_ADD
						S = 4'b1001;
						M=0;
						//C'n = Carry
						ALUcarry = 0; // this is input to ALU
						end   
					2:	if(CARRY_FROM_ALU == 1 || CARRY_FROM_ALU == 1'b1)
							PC_HIGH_INC = 1;
					3:  begin
						PC_LOW_OUT = 0;
						INC = 0;
						PC_LOW_INC = 1;
						end
					4:	i = -1; // reset i, so it starts at 0
								// wait for this because PC_LOW_INC change takes a cycle
					//-----------------------------
					//end increment program counter
					//-----------------------------
					default:; //no op
				endcase // i
				end
	        4'b0001:begin//JC
	                  case(i) 
	                    0:  IR_IN = 1;
						
						1: 	begin
							if(carry_storage == 0 || carry_storage == 1'b0)
								i=11; // skip this stuff
							end
						
						2:	PC_LOW_OUT = 1;

						3:	IR_OUT = 1;
							
						4:	begin
							S = 4'b1001;
							M = 0;
							ALUcarry = 0;
							end
							
						5:	begin
							ACCUM_IN = 1;
							temp_carry = CARRY_FROM_ALU;
							end

						6: begin
							ACCUM_IN = 0;
							IR_OUT = 0;
							PC_LOW_OUT = 0;
							end
							
						7: SMR_IN = 1;
						
						8: begin
							SMR_IN = 0;
							SMR_OUT = 1;
							end
							
						9:	begin
							PC_LOW_IN = 1;
							if( temp_carry == 1 || temp_carry == 1'b1 )
								PC_HIGH_INC = 1;
							end
							
						10:	begin
							PC_LOW_IN = 0;
							PC_HIGH_INC = 0;
							SMR_OUT = 0;
							end
							
						11:	i = -1;
						
						//-------------------------------
						//begin increment program counter
						//-------------------------------
						12: begin
							IR_OUT = 0;
							PC_LOW_OUT = 1;
							INC = 1;
							//ALU_FUNC_ADD
							S = 4'b1001;
							M=0;
							//C'n = Carry
							ALUcarry = 0; // this is input to ALU
						   end   
						13:	if(CARRY_FROM_ALU == 1 || CARRY_FROM_ALU == 1'b1)
								PC_HIGH_INC = 1;
						14:  begin
							PC_LOW_OUT = 0;
							INC = 0;
							PC_LOW_INC = 1;
							end
						15:	i = -1; // reset i, so it starts at 0
									// wait for this because PC_LOW_INC change takes a cycle
						//-----------------------------
						//end increment program counter
						//-----------------------------
							
	                    default:; //no op
	                  endcase // Case(i) //JC
	                end //case 0001 
	        4'b0010:begin//JMP
	                  case(i) 

						0:	IR_IN = 1;
	                    1:	IR_OUT = 1; 
						2:	begin
							PC_HIGH_IN = 1;
							end
						
						3:	IR_OUT = 0;
						4: 	begin
							REG_SELECT = 4'b0000; // RA
							R_OUT = 1;
							end
							
						5:	begin
							S = 4'b1010;
							M = 1;
							ALUcarry = 0;
							INC = 1; // just so there's something at A port
							end
							
						6: 	ACCUM_IN = 1;
						
						7:	begin
							ACCUM_IN = 0;
							INC = 0;
							R_OUT = 0;
							end
							
						8: 	SMR_IN = 1;
						9:	begin
							SMR_IN = 0;
							SMR_OUT = 1;
							end
							
						10:	PC_LOW_IN = 1;
						
						11:	SMR_OUT = 0;
	                
						12: i = -1;
	                    default:; //no op
	                  endcase // Case(i) //JMP
	                end //case 0010  
	        4'b0011:begin //MOV, done
	                  case(i) 
					  
						0: IR_IN = 1;
						
						1: 	begin
							R_OUT = 1;
							REG_SELECT<= {2'b00, IR[3:2]}; //R
							end
						2: 	begin// ALUFUNC B_F
							S = 4'b1010;
							M = 1;
							ALUcarry = 0;
							INC = 1; // just so there's something at input A
							end
							
						3:	ACCUM_IN = 1;
						
						4: 	begin
							ACCUM_IN = 0;
							INC = 0;
							R_OUT = 0;
							end
							
						5:	SMR_IN = 1;
						
						6:	begin
							SMR_IN = 0;
							SMR_OUT = 1;
							end
							
						7:	begin
							REG_SELECT = {2'b00, IR[1:0]};
							R_IN = 1;
							end
							
							
						8:	SMR_OUT = 0;
						
						//-------------------------------
						//begin increment program counter
						//-------------------------------
						9: begin
							IR_OUT = 0;
							PC_LOW_OUT = 1;
							INC = 1;
							//ALU_FUNC_ADD
							S = 4'b1001;
							M=0;
							//C'n = Carry
							ALUcarry = 0; // this is input to ALU
						   end   
						10:	if(CARRY_FROM_ALU == 1 || CARRY_FROM_ALU == 1'b1)
								PC_HIGH_INC = 1;
						11:  begin
							PC_LOW_OUT = 0;
							INC = 0;
							PC_LOW_INC = 1;
							end
						12:	i = -1; // reset i, so it starts at 0
									// wait for this because PC_LOW_INC change takes a cycle
						//-----------------------------
						//end increment program counter
						//-----------------------------
	                    default:; //no op
	                  endcase // Case(i) //MOV
	                end //case 0011 
	        4'b0100:begin //MVI, done
	                  case(i) 

	                    0:	IR_IN = 1;
	                    1:	IR_OUT = 1; 
						2:	begin
							REG_SELECT = 4'b0000;
							R_IN = 1;
							end
							
						//-------------------------------
						//begin increment program counter
						//-------------------------------
	                    3: begin
							IR_OUT = 0;
							PC_LOW_OUT = 1;
							INC = 1;
							//ALU_FUNC_ADD
							S = 4'b1001;
							M=0;
							//C'n = Carry
							ALUcarry = 0; // this is input to ALU
	                       end   
						4:	if(CARRY_FROM_ALU == 1 || CARRY_FROM_ALU == 1'b1)
								PC_HIGH_INC = 1;
						5:  begin
							PC_LOW_OUT = 0;
							INC = 0;
							PC_LOW_INC = 1;
							end
						6:	i = -1; // reset i, so it starts at 0
									// wait for this because PC_LOW_INC change takes a cycle
						//-----------------------------
						//end increment program counter
						//-----------------------------
						
	                    default:; //no op
	                  endcase // Case(i) //MVI
	                end //case 0100 
	        4'b0101:begin//INC, done
	                  case(i)  
	                    0: 	IR_IN <= 1;
						
						
	                    1: 	begin
							R_OUT = 1;
							REG_SELECT<= {2'b00, IR[3:2]}; //R
							end
						2:	begin
							INC = 1;
							S = 4'b1001;
	                        M = 0;
							ALUcarry = carry_storage; //input to ALU
							end
						3:  begin
							ACCUM_IN = 1;
							carry_storage = CARRY_FROM_ALU;
							end
						4:	begin
							ACCUM_IN = 0;
							INC = 0;
							R_OUT = 0;
							end
						5:	SMR_IN = 1;
						6:	begin
							SMR_IN = 0;
							SMR_OUT = 1;
							end
						7:	begin
							REG_SELECT = {2'b00, IR[3:2]}; //RA
							R_IN = 1;
							end
						8:	SMR_OUT = 0;
							
	                    //-------------------------------
						//begin increment program counter
						//-------------------------------
						9: begin
							IR_OUT = 0;
							PC_LOW_OUT = 1;
							INC = 1;
							//ALU_FUNC_ADD
							S = 4'b1001;
							M=0;
							//C'n = Carry
							ALUcarry = 0; // this is input to ALU
						   end   
						10:	if(CARRY_FROM_ALU == 1 || CARRY_FROM_ALU == 1'b1)
								PC_HIGH_INC = 1;
						11:  begin
							PC_LOW_OUT = 0;
							INC = 0;
							PC_LOW_INC = 1;
							end
						12:	i = -1; // reset i, so it starts at 0
									// wait for this because PC_LOW_INC change takes a cycle
						//-----------------------------
						//end increment program counter
						//-----------------------------
					
	                    default:; //no op
	                  endcase // Case(i) //INC
	                end //case 0101       
	        4'b0110:begin//ADD, done
	                  case(i) 
						0: IR_IN = 1;
						
						1: 	begin
							R_OUT = 1;
							REG_SELECT<= {2'b00, IR[3:2]}; // R1
							end
						2: 	begin// ALUFUNC B_F
							S = 4'b1010;
							M = 1;
							ALUcarry = 0;
							INC = 1; // just so there's something at input A
							end
							
						3:	ACCUM_IN = 1;
						
						4: 	begin
							ACCUM_IN = 0;
							INC = 0;
							R_OUT = 0;
							end
							
						5:	SMR_IN = 1;
						
						6:	begin
							SMR_IN = 0;
							SMR_OUT = 1;
							end
							
						7:	begin
							REG_SELECT = {2'b00, IR[1:0]}; // R2
							R_OUT = 1;
							end
							
						8:	begin
							S = 4'b1001;
							M = 0;
							ALUcarry = carry_storage;
							end
							
						9:	begin
							ACCUM_IN = 1;
							carry_storage = CARRY_FROM_ALU;
							end
						
						10: begin
							SMR_OUT = 0;
							ACCUM_IN = 0;
							R_OUT = 0;
							end
							
						11: SMR_IN = 1;
						
						12: begin
							SMR_IN = 0;
							SMR_OUT = 1;
							end
							
						13:	begin
							REG_SELECT = {2'b00, IR[3:2]}; // R1
							R_IN = 1;
							end
							
							
						14:	SMR_OUT = 0;
							
						//-------------------------------
						//begin increment program counter
						//-------------------------------
						15: begin
							IR_OUT = 0;
							PC_LOW_OUT = 1;
							INC = 1;
							//ALU_FUNC_ADD
							S = 4'b1001;
							M=0;
							//C'n = Carry
							ALUcarry = 0; // this is input to ALU
						   end   
						16:	if(CARRY_FROM_ALU == 1 || CARRY_FROM_ALU == 1'b1)
								PC_HIGH_INC = 1;
						17:  begin
							PC_LOW_OUT = 0;
							INC = 0;
							PC_LOW_INC = 1;
							end
						18:	i = -1; // reset i, so it starts at 0
									// wait for this because PC_LOW_INC change takes a cycle
						//-----------------------------
						//end increment program counter
						//-----------------------------
	                    default:; //no op
	                  endcase // Case(i) //ADD
	                end //case 0110     
	                
	        4'b0111:begin//SUB, DONE
	                  case(i) 
	                    0: IR_IN = 1;
						
						1: 	begin
							R_OUT = 1;
							REG_SELECT<= {2'b00, IR[3:2]}; // R1
							end
						2: 	begin// ALUFUNC B_F
							S = 4'b1010;
							M = 1;
							ALUcarry = 0;
							INC = 1; // just so there's something at input A
							end
							
						3:	ACCUM_IN = 1;
						
						4: 	begin
							ACCUM_IN = 0;
							INC = 0;
							R_OUT = 0;
							end
							
						5:	SMR_IN = 1;
						
						6:	begin
							SMR_IN = 0;
							SMR_OUT = 1;
							end
							
						7:	begin
							REG_SELECT = {2'b00, IR[1:0]}; // R2
							R_OUT = 1;
							end
							
						8:	begin
							S = 4'b0110;
							M = 0;
							ALUcarry = ~carry_storage;
							end
							
						9:	begin
							ACCUM_IN = 1;
							carry_storage = ~CARRY_FROM_ALU;
							end
						
						10: begin
							SMR_OUT = 0;
							ACCUM_IN = 0;
							R_OUT = 0;
							end
							
						11: SMR_IN = 1;
						
						12: begin
							SMR_IN = 0;
							SMR_OUT = 1;
							end
							
						13:	begin
							REG_SELECT = {2'b00, IR[3:2]}; // R1
							R_IN = 1;
							end
							
							
						14:	SMR_OUT = 0;
							
						//-------------------------------
						//begin increment program counter
						//-------------------------------
						15: begin
							IR_OUT = 0;
							PC_LOW_OUT = 1;
							INC = 1;
							//ALU_FUNC_ADD
							S = 4'b1001;
							M=0;
							//C'n = Carry
							ALUcarry = 0; // this is input to ALU
						   end   
						16:	if(CARRY_FROM_ALU == 1 || CARRY_FROM_ALU == 1'b1)
								PC_HIGH_INC = 1;
						17:  begin
							PC_LOW_OUT = 0;
							INC = 0;
							PC_LOW_INC = 1;
							end
						18:	i = -1; // reset i, so it starts at 0
									// wait for this because PC_LOW_INC change takes a cycle
						//-----------------------------
						//end increment program counter
						//-----------------------------
	                    default:; //no op
	                  endcase // Case(i) //SUB
	                end //case 0111
	        4'b1000:begin//AND, DONE
	                  case(i) 
					  
					  
					  0: IR_IN = 1;
						
						1: 	begin
							R_OUT = 1;
							REG_SELECT<= {2'b00, IR[3:2]}; // R1
							end
						2: 	begin// ALUFUNC B_F
							S = 4'b1010;
							M = 1;
							ALUcarry = 0;
							INC = 1; // just so there's something at input A
							end
							
						3:	ACCUM_IN = 1;
						
						4: 	begin
							ACCUM_IN = 0;
							INC = 0;
							R_OUT = 0;
							end
							
						5:	SMR_IN = 1;
						
						6:	begin
							SMR_IN = 0;
							SMR_OUT = 1;
							end
							
						7:	begin
							REG_SELECT = {2'b00, IR[1:0]}; // R2
							R_OUT = 1;
							end
							
						8:	begin
							S = 4'b1011;
							M = 1;
							ALUcarry = 0;
							end
							
						9:	ACCUM_IN = 1;
						
						10: begin
							SMR_OUT = 0;
							ACCUM_IN = 0;
							R_OUT = 0;
							end
							
						11: SMR_IN = 1;
						
						12: begin
							SMR_IN = 0;
							SMR_OUT = 1;
							end
							
						13:	begin
							REG_SELECT = {2'b00, IR[3:2]}; // R1
							R_IN = 1;
							end
							
							
						14:	SMR_OUT = 0;
							
						//-------------------------------
						//begin increment program counter
						//-------------------------------
						15: begin
							IR_OUT = 0;
							PC_LOW_OUT = 1;
							INC = 1;
							//ALU_FUNC_ADD
							S = 4'b1001;
							M=0;
							//C'n = Carry
							ALUcarry = 0; // this is input to ALU
						   end   
						16:	if(CARRY_FROM_ALU == 1 || CARRY_FROM_ALU == 1'b1)
								PC_HIGH_INC = 1;
						17:  begin
							PC_LOW_OUT = 0;
							INC = 0;
							PC_LOW_INC = 1;
							end
						18:	i = -1; // reset i, so it starts at 0
									// wait for this because PC_LOW_INC change takes a cycle
						//-----------------------------
						//end increment program counter
						//-----------------------------
						
	                    default:; //no op
	                  endcase // Case(i) //AND
	                end //case 1000
	        4'b1001:begin//OR, done
	                  case(i) 
	                    0: IR_IN = 1;
						
						1: 	begin
							R_OUT = 1;
							REG_SELECT<= {2'b00, IR[3:2]}; // R1
							end
						2: 	begin// ALUFUNC B_F
							S = 4'b1010;
							M = 1;
							ALUcarry = 0;
							INC = 1; // just so there's something at input A
							end
							
						3:	ACCUM_IN = 1;
						
						4: 	begin
							ACCUM_IN = 0;
							INC = 0;
							R_OUT = 0;
							end
							
						5:	SMR_IN = 1;
						
						6:	begin
							SMR_IN = 0;
							SMR_OUT = 1;
							end
							
						7:	begin
							REG_SELECT = {2'b00, IR[1:0]}; // R2
							R_OUT = 1;
							end
							
						8:	begin
							S = 4'b1110;
							M = 1;
							ALUcarry = 0;
							end
							
						9:	ACCUM_IN = 1;
						
						10: begin
							SMR_OUT = 0;
							ACCUM_IN = 0;
							R_OUT = 0;
							end
							
						11: SMR_IN = 1;
						
						12: begin
							SMR_IN = 0;
							SMR_OUT = 1;
							end
							
						13:	begin
							REG_SELECT = {2'b00, IR[3:2]}; // R1
							R_IN = 1;
							end
							
							
						14:	SMR_OUT = 0;
							
						//-------------------------------
						//begin increment program counter
						//-------------------------------
						15: begin
							IR_OUT = 0;
							PC_LOW_OUT = 1;
							INC = 1;
							//ALU_FUNC_ADD
							S = 4'b1001;
							M=0;
							//C'n = Carry
							ALUcarry = 0; // this is input to ALU
						   end   
						16:	if(CARRY_FROM_ALU == 1 || CARRY_FROM_ALU == 1'b1)
								PC_HIGH_INC = 1;
						17:  begin
							PC_LOW_OUT = 0;
							INC = 0;
							PC_LOW_INC = 1;
							end
						18:	i = -1; // reset i, so it starts at 0
									// wait for this because PC_LOW_INC change takes a cycle
						//-----------------------------
						//end increment program counter
						//-----------------------------
	                    default:; //no op
	                  endcase // Case(i) //OR
	                end //case 1001
	        4'b1010:begin//SC, done
	                  case(i)  
	                    0: IR_IN <= 1;
						1: carry_storage = 1;
						//-------------------------------
						//begin increment program counter
						//-------------------------------
						4: begin
							IR_OUT = 0;
							PC_LOW_OUT = 1;
							INC = 1;
							//ALU_FUNC_ADD
							S = 4'b1001;
							M=0;
							//C'n = Carry
							ALUcarry = 0; // this is input to ALU
						   end   
						5:	if(CARRY_FROM_ALU == 1 || CARRY_FROM_ALU == 1'b1)
								PC_HIGH_INC = 1;
						6:  begin
							PC_LOW_OUT = 0;
							INC = 0;
							PC_LOW_INC = 1;
							end
						7:	i = -1; // reset i, so it starts at 0
									// wait for this because PC_LOW_INC change takes a cycle
						//-----------------------------
						//end increment program counter
						//-----------------------------
	                    default:; //no op
	                  endcase // Case(i) //SC
	                end //case 1010
	        4'b1011:begin //CC, done
	                  case(i)
	                    0: IR_IN <= 1;
						1: carry_storage = 0;
						//-------------------------------
						//begin increment program counter
						//-------------------------------
						4: begin
							IR_OUT = 0;
							PC_LOW_OUT = 1;
							INC = 1;
							//ALU_FUNC_ADD
							S = 4'b1001;
							M=0;
							//C'n = Carry
							ALUcarry = 0; // this is input to ALU
						   end   
						5:	if(CARRY_FROM_ALU == 1 || CARRY_FROM_ALU == 1'b1)
								PC_HIGH_INC = 1;
						6:  begin
							PC_LOW_OUT = 0;
							INC = 0;
							PC_LOW_INC = 1;
							end
						7:	i = -1; // reset i, so it starts at 0
									// wait for this because PC_LOW_INC change takes a cycle
						//-----------------------------
						//end increment program counter
						//-----------------------------
	                    default:; //no op
	                  endcase // Case(i) //CC
	                end //case 1011          
	        4'b1100:begin//PUSH, DOne
	                  case(i) 
  
						0: IR_IN = 1;
						
						1: 	begin
							R_OUT = 1;
							REG_SELECT<= {2'b00, IR[3:2]}; //R
							end
						2: 	begin// ALUFUNC B_F
							S = 4'b1010;
							M = 1;
							ALUcarry = 0;
							INC = 1; // just so there's something at input A
							end
							
						3:	ACCUM_IN = 1;
						
						4: 	begin
							ACCUM_IN = 0;
							INC = 0;
							R_OUT = 0;
							end
							
						5:	SMR_IN = 1;
						
						6:	begin
							SMR_IN = 0;
							SMR_OUT = 1;
							end
							
						7:	begin
							REG_SELECT = STACK_PTR + 4;
							R_IN = 1;
							end
							
							
						8:	begin
							SMR_OUT = 0;
							STACK_PTR = STACK_PTR + 1;
							if(STACK_PTR > 8)
								STACK_OVERFLOW = 1;
							else
								STACK_OVERFLOW = 0;
							end
						
						
						//-------------------------------
						//begin increment program counter
						//-------------------------------
						9: begin
							IR_OUT = 0;
							PC_LOW_OUT = 1;
							INC = 1;
							//ALU_FUNC_ADD
							S = 4'b1001;
							M=0;
							//C'n = Carry
							ALUcarry = 0; // this is input to ALU
						   end   
						10:	if(CARRY_FROM_ALU == 1 || CARRY_FROM_ALU == 1'b1)
								PC_HIGH_INC = 1;
						11:  begin
							PC_LOW_OUT = 0;
							INC = 0;
							PC_LOW_INC = 1;
							end
						12:	i = -1; // reset i, so it starts at 0
									// wait for this because PC_LOW_INC change takes a cycle
						//-----------------------------
						//end increment program counter
						//-----------------------------
	                    default:; //no op
	                  endcase // Case(i) //PUSH
	                end //case 1100
	        4'b1101:begin//POP, Done
	                  case(i) 
						0: 	begin
							IR_IN = 1;
							end
						
						1: 	begin 
							if(STACK_PTR == 0)
								STACK_UNDERFLOW = 1;
							else
								begin
								STACK_PTR = STACK_PTR - 1;
								STACK_UNDERFLOW = 0;
								end
							end
							
						
						2: 	begin
							REG_SELECT = STACK_PTR + 4;
							R_OUT = 1;
							end
						3: 	begin// ALUFUNC B_F
							S = 4'b1010;
							M = 1;
							ALUcarry = 0;
							INC = 1; // just so there's something at input A
							end
							
						4:	ACCUM_IN = 1;
						
						5: 	begin
							ACCUM_IN = 0;
							INC = 0;
							R_OUT = 0;
							end
							
						6:	SMR_IN = 1;
						
						7:	begin
							SMR_IN = 0;
							SMR_OUT = 1;
							end
							
						8:	begin
							REG_SELECT<= {2'b00, IR[3:2]}; //R
							R_IN = 1;
							end
							
							
						9:	begin
							SMR_OUT = 0;
							end
						
						
						//-------------------------------
						//begin increment program counter
						//-------------------------------
						10: begin
							IR_OUT = 0;
							PC_LOW_OUT = 1;
							INC = 1;
							//ALU_FUNC_ADD
							S = 4'b1001;
							M=0;
							//C'n = Carry
							ALUcarry = 0; // this is input to ALU
						   end   
						11:	if(CARRY_FROM_ALU == 1 || CARRY_FROM_ALU == 1'b1)
								PC_HIGH_INC = 1;
						12:  begin
							PC_LOW_OUT = 0;
							INC = 0;
							PC_LOW_INC = 1;
							end
						13:	i = -1; // reset i, so it starts at 0
									// wait for this because PC_LOW_INC change takes a cycle
						//-----------------------------
						//end increment program counter
						//-----------------------------
	                    default:; //no op
	                  endcase // Case(i) //POP
	                end //case 1101   
	        4'b1110:begin //IN, done
	               case(i) 
						0: 	IR_IN = 1;
						
						1:	DIP_OUT = 1;
						
						2:	begin
							REG_SELECT = {2'b00, IR[3:2]}; //RA
							R_IN = 1;
							end
						3:	DIP_OUT = 0;
							
	                    //-------------------------------
						//begin increment program counter
						//-------------------------------
						4: begin
							IR_OUT = 0;
							PC_LOW_OUT = 1;
							INC = 1;
							//ALU_FUNC_ADD
							S = 4'b1001;
							M=0;
							//C'n = Carry
							ALUcarry = 0; // this is input to ALU
						   end   
						5:	if(CARRY_FROM_ALU == 1 || CARRY_FROM_ALU == 1'b1)
								PC_HIGH_INC = 1;
						6:  begin
							PC_LOW_OUT = 0;
							INC = 0;
							PC_LOW_INC = 1;
							end
						7:	i = -1; // reset i, so it starts at 0
									// wait for this because PC_LOW_INC change takes a cycle
						//-----------------------------
						//end increment program counter
						//-----------------------------
					
	              endcase //case(i) IN
	            end //case b1110
	        4'b1111:begin //OUT, done
	               case(i) 
	                0: IR_IN <= 1;
	                1: 	begin
						REG_SELECT = {2'b00, IR[3:2]};
						R_OUT = 1;
						end
					2:	begin
						LED_REG_IN = 1;
						end
	                3:	R_OUT = 0; // manually disable
					//-------------------------------
					//begin increment program counter
					//-------------------------------
					4: begin
						IR_OUT = 0;
						PC_LOW_OUT = 1;
						INC = 1;
						//ALU_FUNC_ADD
						S = 4'b1001;
						M=0;
						//C'n = Carry
						ALUcarry = 0; // this is input to ALU
					   end   
					5:	if(CARRY_FROM_ALU == 1 || CARRY_FROM_ALU == 1'b1)
							PC_HIGH_INC = 1;
					6:  begin
						PC_LOW_OUT = 0;
						INC = 0;
						PC_LOW_INC = 1;
						end
					7:	i = -1; // reset i, so it starts at 0
								// wait for this because PC_LOW_INC change takes a cycle
					//-----------------------------
					//end increment program counter
					//-----------------------------
					
	              endcase //case(i)
	            end //case(4'b1111)  
			default: begin
				// IR_IN needs to start high, so it can read in the IR from EEPROM to work...
				if(firstStep && i==1) begin
					IR_IN = 1;
					firstStep = 0;
					i=-1; // reset i so it'll hop to 0
				end // if firststep
				else
					IR_IN = 0;
					
			end // case (default)
	      endcase // case(opcode)
	    i = i+1; //increment the step pointer
	  end end // there are two because i added an if / else for rst  
	endmodule
